package com.um.springboot.starter.utils;

import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class ReflectUtil {

	/**
	 * 获得一个对象的属性值
	 * @param obj 对象
	 * @param property 属性名称
	 * @return 属性值
	 */
	public static Object getValue(Object obj,String property){
		try {
			String methodName = "get" + property.substring(0, 1).toUpperCase() + property.substring(1);
			Method method = obj.getClass().getMethod(methodName);
            return method.invoke(obj);
        } catch (NoSuchMethodException e) {
			//log.warn(e.getMessage());
		} catch (Exception e) {
			log.error("", e);
		}
		return null;
	}

	/**
	 * 设置对象的属性值
	 * @param obj 对象
	 * @param property 属性名称
	 * @param value 属性值
	 */
	@SuppressWarnings("unchecked")
	public static void setValue(Object obj,String property,Object value){
		if (value == null) {
			return;
		}
		try {
			String methodName = "set" + property.substring(0, 1).toUpperCase() + property.substring(1);
			Class[] param = new Class[1];
			Field field = obj.getClass().getDeclaredField(property);
			param[0] = field.getType();
			Method method = obj.getClass().getDeclaredMethod(methodName, param);
			if (field.getType().getSimpleName().equals("Date")) {
				if (!value.toString().isEmpty())
					method.invoke(obj, DateUtil.to_date(value + ""));
			} else if (field.getType().getSimpleName().equals("Integer")) {
				method.invoke(obj, StringUtil.toInt(value));
			} else if (field.getType().getSimpleName().equals("Float")) {
				method.invoke(obj, StringUtil.toFloat(value));
			} else if (field.getType().getSimpleName().equals("Double")) {
				method.invoke(obj, StringUtil.toDouble(value));
			} else {
				method.invoke(obj, value);
			}
		} catch (NoSuchMethodException | NoSuchFieldException e) {
			//log.warn(e.getMessage());
		} catch (Exception e) {
			log.error("", e);
		}
	}

	/**
	 * 按类的全称反射生成一个类
	 * @param className 类的全称
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Object newInstance(String className){
		try{
			Class cls = Class.forName(className);
			return cls.newInstance();
		}catch(Exception e){
			log.error("", e);
		}
		return null;
	}

	public static Object newInstance(Class clazz){
		try{
			return clazz.newInstance();
		}catch(Exception e){
			log.error("", e);
		}
		return null;
	}

	/**
	 * 获得类的名称
	 * @param obj 对象
	 * @return
	 */
	public static String getClassName(Object obj){
		try{
			String className = obj.getClass().getName();
			return className;
		}catch(Exception ex){
			log.error("通过反射获得类名出错!");
		}
		return "";
	}

	public static void copyValues(Map source, Object target){
		Iterator it = source.keySet().iterator();
		while(it.hasNext()){
			String key = it.next().toString();
			String property = underlineToHump(key);
			setValue(target,property,source.get(key));
		}
	}

	private static Pattern UNDERLINE_PATTERN = Pattern.compile("_([a-z])");


	/**
	 * 根据传入的带下划线的字符串转化为驼峰格式
	 * @param str
	 * @author mrf
	 * @return
	 */

	public static  String underlineToHump (String str){
		//正则匹配下划线及后一个字符，删除下划线并将匹配的字符转成大写
		Matcher matcher = UNDERLINE_PATTERN.matcher(str);
		StringBuffer sb = new StringBuffer(str);
		if (matcher.find()) {
			sb = new StringBuffer();
			//将当前匹配的子串替换成指定字符串，并且将替换后的子串及之前到上次匹配的子串之后的字符串添加到StringBuffer对象中
			//正则之前的字符和被替换的字符
			matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
			//把之后的字符串也添加到StringBuffer对象中
			matcher.appendTail(sb);
		} else {
			//去除除字母之外的前面带的下划线
			return sb.toString().replaceAll("_", "");
		}
		return underlineToHump(sb.toString());
	}

//	public static void main(String[] args){
//		System.out.println(underlineToHump("end_time"));
//	}


}
